package com.xyoto.community.service.impl;

import com.xyoto.community.cache.CacheInstruction;
import com.xyoto.community.config.TopicUserHotTableConfig;
import com.xyoto.community.constant.DatabaseOperationResult;
import com.xyoto.community.constant.TopicUserHotType;
import com.xyoto.community.dto.AddTopicUserHotDTO;
import com.xyoto.community.dto.TopicUserHotDTO;
import com.xyoto.community.entity.main.OtherTopicUserHot;
import com.xyoto.community.mapper.main.OtherTopicUserHotMapper;
import com.xyoto.community.mapper.main.TopicUserHotMapper;
import com.xyoto.community.pojo.Type2TopicUserHotTableInfo;
import com.xyoto.community.service.TopicUserHotService;
import com.xyoto.community.utils.RedisCommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 话题用户活跃度service实现类
 */
@Slf4j
@Service
public class TopicUserHotServiceImpl implements TopicUserHotService {

    @Resource
    private TopicUserHotTableConfig topicUserHotTableConfig;

    @Resource
    private TopicUserHotMapper topicUserHotMapper;

    @Resource
    private RedisCommonUtils redisCommonUtils;

    @Resource
    private OtherTopicUserHotMapper otherTopicUserHotMapper;

    /**
     * 增加用户在话题中的活跃度，异步执行
     *
     * @param addTopicUserHotDTO 话题下的用户活跃度dto
     */
    @Override
    public void addHot(AddTopicUserHotDTO addTopicUserHotDTO) {
        // 根据话题id获取该话题对应的用户活跃度表
        Integer topicId = addTopicUserHotDTO.getTopicId();
        Type2TopicUserHotTableInfo topicUserHotInfo =
                topicUserHotTableConfig.getTopicUserHotInfoByTopicId(topicId);
        Double score = topicUserHotTableConfig.getScoreByOperateType(addTopicUserHotDTO.getType());

        // 在用户总榜表中加入用户热度
        OtherTopicUserHot otherTopicUserHot = new OtherTopicUserHot(
                addTopicUserHotDTO.getUserId()
                , addTopicUserHotDTO.getType()
                , topicId, score);
        Integer insert = otherTopicUserHotMapper.insertOne(otherTopicUserHot);
        if (insert < DatabaseOperationResult.SUCCESS) {
            log.warn("【增加用户在话题下的活跃度】插入otherTopicUserHot表出错，实体参数为：{}", otherTopicUserHot);
        }

        // 在redis的用户总榜中给用榜加分
        Double userRankScoreFromCache = redisCommonUtils.getScore(CacheInstruction.USER_RANK,addTopicUserHotDTO.getUserId());
        if (userRankScoreFromCache == null || userRankScoreFromCache == -1.0) {
            // 用户第一次在该话题下活跃
            redisCommonUtils.zSet(CacheInstruction.USER_RANK, addTopicUserHotDTO.getUserId(), otherTopicUserHot.getScore());
        } else {
            // 直接增加活跃度
            redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK, addTopicUserHotDTO.getUserId(), otherTopicUserHot.getScore());
        }

        if (topicUserHotInfo != null) {
            // 说明该话题有单独的用户排行榜单
            TopicUserHotDTO topicUserHotDTO = new TopicUserHotDTO();
            topicUserHotDTO.setUserId(addTopicUserHotDTO.getUserId());
            topicUserHotDTO.setType(addTopicUserHotDTO.getType());
            topicUserHotDTO.setScore(score);
            topicUserHotDTO.setTableName(topicUserHotInfo.getTableName());
            // 用户操作记录写入活跃度表中
            insert = topicUserHotMapper.insertOne(topicUserHotDTO);
            if (insert < DatabaseOperationResult.SUCCESS) {
                log.warn("【增加用户在话题下的活跃度】，插入数据库失败，实体参数：{}，表名：{}"
                        , topicUserHotDTO, topicUserHotInfo.getTableName());
            }
            // 更新redis中该用户在该话题下的活跃度
            Double scoreFromCache = redisCommonUtils.getScore(topicUserHotInfo.getTableName(), topicUserHotDTO.getUserId());
            if (scoreFromCache == null || scoreFromCache == -1.0) {
                // 用户第一次在该话题下活跃
                redisCommonUtils.zSet(topicUserHotInfo.getTableName(), topicUserHotDTO.getUserId()
                        , topicUserHotDTO.getScore().doubleValue());
            } else {
                // 增加活跃度
                redisCommonUtils.incrementScoreForZSet(topicUserHotInfo.getTableName()
                        , addTopicUserHotDTO.getUserId(), score.doubleValue());
            }
        }
    }

    /**
     * 给用户加分
     * @author 廖振辉
     * @param userId 用户id
     * @param topicId 话题id
     * @param type 加分类型
     * @return {@link }
     */
    @Override
    @Async
    public void addHot(Integer userId, Integer topicId, Integer type) {
        if (topicId == null){
            // 若没有话题id则置为0
            topicId = 0;
        }
        if (userId == 0){
            // 不存在0号用户，如话题的主人是官方自定的，则传进来的用户id可能为0
            return;
        }
        AddTopicUserHotDTO addTopicUserHotDTO = new AddTopicUserHotDTO();
        addTopicUserHotDTO.setUserId(userId);
        addTopicUserHotDTO.setTopicId(topicId);
        addTopicUserHotDTO.setType(type);
        addHot(addTopicUserHotDTO);
    }
}
